package com.gitee.wsl.common.ui.ext.color

import androidx.compose.ui.graphics.Color
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min

/**
 * Instantiate a color from an Int. It should be used
 * using the HEX code like this : `0x0b0b0b.col`
 */
val Int.toColor: Color
    get() = Color(this)

//private val regex: Regex by lazy { """^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$""".toRegex() }



fun RGBtoHSB(fromArgb: Int): FloatArray {
    val r = fromArgb ushr 16 and 0xFF
    val g = fromArgb ushr 8 and 0xFF
    val b = fromArgb ushr 0 and 0xFF

    return RGBtoHSB(r = r / 255.0f, g = g / 255.0f, b = b / 255.0f)
}

fun RGBtoHSB(from: Color): FloatArray {
    return RGBtoHSB(from.red, from.green, from.blue)
}

// See https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
fun RGBtoHSB(r: Float, g: Float, b: Float): FloatArray {
    val result = FloatArray(3)

    val xmax = max(max(r, g), b)
    val xmin = min(min(r, g), b)
    val chroma = xmax - xmin

    // brightness
    result[2] = xmax
    // saturation
    result[1] = if (result[2] == 0.0f) 0.0f else chroma / result[2]
    // hue
    if (chroma == 0.0f) {
        result[0] = 0.0f
    } else {
        if (xmax == r) {
            result[0] = (1.0f / 6.0f) * ((g - b) / chroma)
        } else if (xmax == g) {
            result[0] = (1.0f / 6.0f) * (2 + (b - r) / chroma)
        } else {
            result[0] = (1.0f / 6.0f) * (4 + (r - g) / chroma)
        }
        if (result[0] < 0.0f) {
            result[0] = 0.0f
        }
    }
    return result
}

// See https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB
fun HSBtoRGB(from: FloatArray): Color {
    val hue = from[0]
    val saturation = from[1]
    val brightness = from[2]

    if (saturation == 0.0f) {
        return Color(brightness, brightness, brightness)
    }

    val hue360 = hue * 360.0f
    val hue360sharp = hue360 / 60.0f

    val chroma = saturation * brightness
    val x = chroma * (1 - abs(hue360sharp % 2 - 1))
    val m = brightness - chroma

    if ((hue360sharp >= 0.0f) && (hue360sharp <= 1.0f)) {
        return Color(chroma + m, x + m, m)
    }
    if (hue360sharp <= 2.0f) {
        return Color(x + m, chroma + m, m)
    }
    if (hue360sharp <= 3.0f) {
        return Color(m, chroma + m, x + m)
    }
    if (hue360sharp <= 4.0f) {
        return Color(m, x + m, chroma + m)
    }
    if (hue360sharp <= 5.0f) {
        return Color(x + m, m, chroma + m)
    }
    return Color(chroma + m, m, x + m)
}

/**
 * Instantiate a color from an String representing its hexadecimal value.
 * Ex: "#12abCD".col
 */
val String.hexToColor: Color
    get():Color {
        return Hex(this).color()
        /*require(this.matches(regex)) {
            "Conversion of string to io.data2viz.col.RgbColor works for encoded colors like #12abCD"
        }
        return Color(substring(1).toInt(16))*/
    }

fun Color.Companion.parser(value:String):Color? = ColorUtils.toColor(value)

/**
 * Check if the passed String is valid CSS RGB color value.
 * Example value: rgb(255,0,0)
 */
fun Color.Companion.isRGBColorValue(value: String): Boolean = ColorUtils.isRGBColorValue(value)
/**
 * Check if the passed String is valid CSS RGBA color value.
 * Example value: rgba(255,0,0, 0.1)
 */
fun Color.Companion.isRGBAColorValue(value: String): Boolean = ColorUtils.isRGBAColorValue(value)

/**
 * Check if the passed String is valid CSS HSL color value.
 * Example value: hsl(255,0%,0%)
 */
fun Color.Companion.isHSLColorValue(value: String): Boolean = ColorUtils.isHSLColorValue(value)

/**
 * Check if the passed String is valid CSS HSLA color value.
 * Example value: hsla(255,0%,0%, 0.1)
 */
fun Color.Companion.isHSLAColorValue(value: String): Boolean = ColorUtils.isHSLAColorValue(value)


